#include "../src/log.h"
#include <pthread.h>
#include <signal.h>

bool s_stop = false;
pthread_mutex_t MUTEX_LOG;
void log_lock(bool lock, void *udata);

void log_lock(bool lock, void* udata) {
    pthread_mutex_t *LOCK = (pthread_mutex_t*)(udata);
    if (lock)
        pthread_mutex_lock(LOCK);
    else
        pthread_mutex_unlock(LOCK);
}

void run(void *arg) {
    int id = *(int*)arg;
    unsigned int idx = 0;
    for (;;) {
    	log_debug("thread_id:%d idx:%u", id, idx++);
	    usleep(1000 * 200);
	    if (s_stop) break;
    }
}

void run1(void *arg) {
    struct KFIFO* fifo = (struct KFIFO*)arg;
    unsigned char buffer[256] = {0};
    for (;;) {
        // write的时候加了锁，相当于只有一个writer, 一个reader，所以读取的时候不用加锁
        // pthread_mutex_lock(&MUTEX_LOG);
        memset(buffer, 0, sizeof(buffer));
        unsigned int len = kfifo_get(fifo, buffer, 256);
        // 如果len =256则表示数据已满，读取的不及时，数据会被覆盖
        // 要么增大buffer，要么提高读取频率
        if (len > 0)
            printf("+len:%d %s\n", len, buffer);
        // pthread_mutex_unlock(&MUTEX_LOG);
        usleep(1000 * 15);
        if (s_stop) break;
    }
}

void stop(int signo) {
    (void)signo;
    s_stop = true;
}

int main() {
    pthread_mutex_init(&MUTEX_LOG, NULL);
    log_set_lock(log_lock, &MUTEX_LOG);

    FILE* fp = fopen ("demo.log", "a+");
    struct KFIFO* fifo = kfifo_alloc(4000);
    kfifo_init(fifo);

    log_set_quiet(true);
    log_set_enable_time(true);
    log_set_level(LOG_DEBUG);
    log_set_fullpath(false);
    log_add_fp(fp, LOG_DEBUG);
    log_add_mem(fifo, LOG_DEBUG);

    signal(SIGINT, stop);
    signal(SIGKILL, stop);
    signal(SIGTERM, stop);

    int SIZE = 8;
    pthread_t h[SIZE];
    int id_array[8] = {0,1,2,3,4,5,6,7};
    for (int i= 0; i<SIZE; i++) {
        pthread_create(&h[i], NULL, run, &id_array[i]);
    }

    // 异步日志线程参考实现，目前是输出到stdout
    pthread_t h1;
    pthread_create(&h1, NULL, run1, fifo);
    pthread_join(h1, NULL);

    void* ret[8] = {NULL};
    for (int i=0; i<8; i++) {
        pthread_join(h[i], &ret);
    }

    pthread_mutex_destroy(&MUTEX_LOG);
    kfifo_free(fifo);
    fclose(fp);
}
